﻿using DetectScars.model;
using ScottPlot;
using ScottPlot.Colormaps;
using ScottPlot.WinForms;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Runtime.InteropServices.JavaScript.JSType;
using Timer = System.Windows.Forms.Timer;

namespace DetectScars.common
{
    class SocketServer_
    {
        static FormsPlot? formsPlot_;
        static ComboBox? comboBox_;
        static int count = 0;
        static int sum = 0;
        static Thread thread;
        static Socket serverSocket;
        static string data = "";
        static double[][] dataY = null;
        private static List<Gate> gates_ = null;
        private static string dac_data;

        internal static void SetGates(List<Gate> gates)
        {
            gates_ = gates;
        }
        internal static void SetDacData(string dac)
        {
            dac_data = dac;
        }
        //初始化
        public static void Init()
        {
            //初始化
            //创建一个Socket服务端
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            string serverIp = "127.0.0.1";
            //string serverIp = "127.0.0.1";
            int serverPort = 1001;
            serverSocket.Bind(new IPEndPoint(IPAddress.Parse(serverIp), serverPort));
            serverSocket.Listen(10);
            // 创建监听事件
            thread = new Thread(ListenClientConnect);
            thread.Start(serverSocket);
            //创建20毫秒刷新一次的定时器
            Timer timer = new Timer();
            timer.Interval = 20;
            timer.Tick += new EventHandler((object sender, EventArgs e) =>
            {
                DisplayData();
            });
            timer.Start();


        }


        static double[][] ConvertTo2DArray(ReadOnlySpan<float> flatArray, int rows, int cols)
        {
            double[][] result = new double[rows][];
            for (int i = 0; i < rows; i++)
            {
                result[i] = new double[cols];
                for (int j = 0; j < cols; j++)
                    result[i][j] = flatArray[i * cols + j];
            }
            return result;
        }

        private static void DisplayData()
        {
            try
            {
                if (data != "")
                {
                    //:分割data
                    string[] dataArr = data.Split(":");
                    int rows = int.Parse(dataArr[0]);
                    int cols = int.Parse(dataArr[1]);
                    //解析数据
                    if (dataY == null)
                    {
                        return;
                    }
                    int index = 0;
                    //创建一个推托事件让comboBox_更新数据
                    if (comboBox_ != null)
                    {
                        //创建一个推托事件让comboBox_更新数据
                        comboBox_.Invoke(new Action(() =>
                        {
                            if (rows != count)
                            {
                                count = rows;
                                //更新下拉框
                                comboBox_.Items.Clear();
                                for (int i = 0; i < count; i++)
                                {
                                    comboBox_.Items.Add("第" + (i + 1) + "组");
                                }
                                comboBox_.SelectedIndex = 0;
                            }
                            else
                            {
                                index = comboBox_.SelectedIndex;
                            }
                        }));
                    }
                    
                    if (formsPlot_ == null)
                    {
                        return;
                    }
                    //创建一个推托事件让formsPlot_更新数据
                    formsPlot_.Invoke(new Action(() =>
                    {
                        formsPlot_.Plot.Clear();
                        //采样率
                        double cy = double.Parse(formsPlot_.Tag.ToString())/ cols;
                        formsPlot_.Plot.Add.Signal(dataY[index],cy);
                        //闸门
                        foreach (Gate gate in gates_)
                        {
                            if (gate.IsDeleted)
                            {
                                continue;
                            }
                            if (gate.enabled)
                            {
                                //.VSpan(gate.start_us, gate.stop_us, Color.Red, Color.Red)
                                formsPlot_.Plot.Add.Line(new Coordinates(gate.start_us, gate.threshold_pct), new Coordinates(gate.stop_us, gate.threshold_pct));
                            }
                        }
                        //dac画自然曲线
                        if (dac_data != "")
                        {
                            string[] dacArr = dac_data.Split(";");
                            string[] tofs = dacArr[0].Split(",");
                            string[] gains = dacArr[1].Split(",");
                            double[] x = new double[tofs.Length];
                            double[] y = new double[tofs.Length];
                            for(int i = 0; i < tofs.Length; i++)
                            {
                                int index_ = (int)((double.Parse(tofs[i]) / double.Parse(formsPlot_.Tag.ToString())) * cols);
                                x[i] = double.Parse(tofs[i]);
                                y[i] = dataY[index][index_];
                            }
                            //自然曲线
                            formsPlot_.Plot.Add.ScatterLine(x, y);
                        }

                        formsPlot_.Refresh();
                        
                        //获取当前时间戳
                        long timeStamp = new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds();
                        formsPlot_.Plot.Axes.Left.Label.Text = timeStamp.ToString() + "===" + sum;
                        data = "";
                    }));
                    
                }
            }
            catch (Exception e)
            {
                LogUtils.WriteLog(e.Message);
                data = "";
            }
        }

        //销毁线程
        public static void Destroy()
        {
            serverSocket.Close();
        }





        private static void ListenClientConnect(object? obj)
        {
            if(obj == null)
            {
                return;
            }
            Socket serverSocket = (Socket)obj;
            while (true)
            {
                try
                {
                    Socket clientSocket = serverSocket.Accept();
                    while (true)
                    {
                        //设置接收超时时间
                        clientSocket.ReceiveTimeout = 1000;
                        byte[] lengthBuffer = new byte[100];
                        int receivedBytes = clientSocket.Receive(lengthBuffer);
                        if (receivedBytes != lengthBuffer.Length)
                        {
                            break;
                        }
                        
                        
                        int rows = BitConverter.ToInt32(lengthBuffer.Reverse().ToArray(), 8);
                        int cols = BitConverter.ToInt32(lengthBuffer.Reverse().ToArray(), 4);
                        int messageLength = BitConverter.ToInt32(lengthBuffer.Reverse().ToArray(), 12);
                        sum = BitConverter.ToInt32(lengthBuffer.Reverse().ToArray(), 0);
                        // 读取实际消息
                        byte[] messageBuffer = new byte[messageLength];
                        int totalReceived = 0;
                        while (totalReceived < messageLength)
                        {
                            int received = clientSocket.Receive(messageBuffer, totalReceived, messageLength - totalReceived, SocketFlags.None);
                            if (received == 0)
                            {
                                break;
                            }
                            totalReceived += received;
                        }
                        ReadOnlySpan<byte> byteSpan = new ReadOnlySpan<byte>(messageBuffer);
                        // 使用 MemoryMarshal.Cast 进行高效转换（零拷贝）
                        ReadOnlySpan<float> floatSpan = MemoryMarshal.Cast<byte, float>(byteSpan);
                        // 转换为二维数组
                        dataY = ConvertTo2DArray(floatSpan, rows, cols);
                        data  = rows + ":" + cols;
                        if (!clientSocket.Connected)
                        {
                            break;
                        }

                        
                    }
                    if(!clientSocket.Connected)
                    {
                        clientSocket.Close();
                    }


                }
                catch (Exception e)
                {
                    LogUtils.WriteLog(e.Message);
                }
                
            }
        }
    }
}
